package com.pan.cuiniubi.create.dao;

import com.pan.cuiniubi.entity.*;
import com.pan.cuiniubi.enumn.OperationEnum;
import com.pan.cuiniubi.utils.ReadYamlTool;
import com.pan.cuiniubi.enumn.LaminaEnum;

import java.util.List;

public abstract class CreateDaoMappingImpl implements CreateDaoMapping {

    public String daoTemplate;

    public String mappingTemplate;

    public String sqlStrTemplate;

    public String importString;

    public String packageStr;


    {

        sqlStrTemplate = "<[[0]] id=\"[[2]]\" [[3]] >\n\t[[1]]\n</[[0]]>";

        importString= "import java.util.List;\n" +
                "import org.apache.ibatis.annotations.Mapper;\n";


        daoTemplate = "@Mapper\npublic interface (0) {\n" +
                "(1)\n};\n";

        mappingTemplate = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" +
                "<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\"\n" +
                "\"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n" +
                "<mapper namespace=\"[[0]]\">\n[[1]]\n</mapper>";
    }
    @Override
    public String getPackageStr(){
        if (packageStr == null) {
            String path = (String) ReadYamlTool.getInstance().getMapLaminaValue(LaminaEnum.dao, "path");
            packageStr = "package " + path + ";\n";
        }
        return packageStr;
    }

    @Override
    public String getClassName(String name, OperationEnum operationEnum,LaminaEnum laminaEnum){
        String opt = operationEnum.name();
        opt = opt.substring(0,1).toUpperCase()+opt.substring(1);
        String lamina = laminaEnum.name();
        lamina = lamina.substring(0,1).toUpperCase()+lamina.substring(1);
        String result = name+opt+lamina;
        return result;
    }
    public String getClassName(String name, OperationEnum operationEnum){
        return getClassName(name,operationEnum,LaminaEnum.dao);
    }

    public String getNamespace(String name,OperationEnum operationEnum){
        String className = getClassName(name,operationEnum);
        String namespace = ReadYamlTool.getInstance().getMapLaminaValue(LaminaEnum.dao,"path")+"."+className;
        return namespace;
    }

    @Override
    public String getImportString(Table table){
        String entityPath = (String) ReadYamlTool.getInstance()
                .getMapLaminaValue(LaminaEnum.entity,"path");
        String entityImportStr = "import "+entityPath+"."+table.getTableName()+";\n";

        List<Member> memberList = table.getMemberList();
        String result = memberList.stream().map(Member::getMemberType)
                .map(Class::getName).map(name->"import "+name+";\n")
                .reduce((x,y)->x+y).get();
        result+=entityImportStr;
        result+="\nimport org.apache.ibatis.annotations.Mapper;\n";
        return result;
    }

    @Override
    public String getDaoContent(DaoInfo daoInfo) {
        String packageString = daoInfo.getPackageStr();
        String importString = daoInfo.getImportStr();
        String className = daoInfo.getClassName();
        String methodStr = daoInfo.getMethodInfoList().stream().map(MethodInfo::getMethodLineStr)
                .reduce((a,b)->a+b).get();
        String result=daoTemplate;
        result = result.replace("(0)",className)
                .replace("(1)",methodStr);
        result = packageString +"\n"+ importString +"\n"+ result;
        return result;
    }



    public String getMappingContent(MappingInfo mappingInfo){
        String mappingString = mappingTemplate;

        String sqlString = mappingInfo.getSqlInfoList().stream()
                .map(sqlInfo->{
                    String sqlStr = sqlStrTemplate;
                    String operation = sqlInfo.getOpt();
                    String sql = sqlInfo.getSql();
                    String id = sqlInfo.getId();
                    String resultType = sqlInfo.getResult();
                    sqlStr = sqlStr.replace("[[0]]",operation)
                            .replace("[[1]]",sql)
                            .replace("[[2]]",id)
                            .replace("[[3]]",resultType==null?"":"resultType=\""+resultType+"\"");
                    return sqlStr;
                }).reduce((x,y)->x+"\n"+y).get();
        String namespace = mappingInfo.getNamespace();

        mappingString = mappingString.replace("[[0]]",namespace)
                .replace("[[1]]",sqlString);
        return mappingString;
    }

}
